home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / Gnuplot / Source / standard.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-02  |  20.2 KB  |  997 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: standard.c%v 3.38.2.78 1993/02/20 03:16:29 woo Exp woo $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - standard.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  * Send your comments or suggestions to 
  35.  *  info-gnuplot@dartmouth.edu.
  36.  * This is a mailing list; to join it send a note to 
  37.  *  info-gnuplot-request@dartmouth.edu.  
  38.  * Send bug reports to
  39.  *  bug-gnuplot@dartmouth.edu.
  40.  */
  41.  
  42. #include <math.h>
  43. #include <stdio.h>
  44. #include "plot.h"
  45.  
  46. #ifdef vms
  47. #include <errno.h>
  48. #else
  49. extern int errno;
  50. #endif /* vms */
  51.  
  52.  
  53. extern struct value stack[STACK_DEPTH];
  54. extern int s_p;
  55. extern double zero;
  56.  
  57. struct value *pop(), *Gcomplex(), *Ginteger();
  58.  
  59. double magnitude(), angle(), real(), imag();
  60.  
  61. /* The bessel function approximations here are from
  62.  * "Computer Approximations"
  63.  * by Hart, Cheney et al.
  64.  * John Wiley & Sons, 1968
  65.  */
  66.  
  67. /* There appears to be a mistake in Hart, Cheney et al. on page 149.
  68.  * Where it list Qn(x)/x ~ P(z*z)/Q(z*z), z = 8/x, it should read
  69.  *               Qn(x)/z ~ P(z*z)/Q(z*z), z = 8/x
  70.  * In the functions below, Qn(x) is implementated using the later
  71.  * equation.
  72.  * These bessel functions are accurate to about 1e-13
  73.  */
  74.  
  75. #if defined (ATARI) && defined(__PUREC__)
  76. /* Sorry. But PUREC bugs here.
  77.  * These bessel functions are NOT accurate to about 1e-13
  78.  */
  79.  
  80. #define PI_ON_FOUR     0.785398163397448309615661
  81. #define PI_ON_TWO     1.570796326794896619231313
  82. #define THREE_PI_ON_FOUR 2.356194490192344928846982
  83. #define TWO_ON_PI     0.636619772367581343075535
  84.  
  85. static double dzero = 0.0;
  86.  
  87. /* jzero for x in [0,8]
  88.  * Index 5849, 19.22 digits precision
  89.  */
  90. static double pjzero[] = {
  91.      0.493378725179413356181681e+21,
  92.     -0.117915762910761053603844e+21,
  93.      0.638205934107235656228943e+19,
  94.     -0.136762035308817138686542e+18,
  95.      0.143435493914034611166432e+16,
  96.     -0.808522203485379387119947e+13,
  97.      0.250715828553688194555516e+11,
  98.     -0.405041237183313270636066e+8,
  99.      0.268578685698001498141585e+5
  100. };
  101.  
  102. static double qjzero[] = {
  103.      0.493378725179413356211328e+21,
  104.      0.542891838409228516020019e+19,
  105.      0.302463561670946269862733e+17,
  106.      0.112775673967979850705603e+15,
  107.      0.312304311494121317257247e+12,
  108.      0.669998767298223967181403e+9,
  109.      0.111463609846298537818240e+7,
  110.      0.136306365232897060444281e+4,
  111.      0.1e+1
  112. };
  113.  
  114. /* pzero for x in [8,inf]
  115.  * Index 6548, 18.16 digits precision
  116.  */
  117. static double ppzero[] = {
  118.      0.227790901973046843022700e+5,
  119.      0.413453866395807657967802e+5,
  120.      0.211705233808649443219340e+5,
  121.      0.348064864432492703474453e+4,
  122.      0.153762019090083542957717e+3,
  123.      0.889615484242104552360748e+0
  124. };
  125.  
  126. static double qpzero[] = {
  127.      0.227790901973046843176842e+5,
  128.      0.413704124955104166398920e+5,
  129.      0.212153505618801157304226e+5,
  130.      0.350287351382356082073561e+4,
  131.      0.157111598580808936490685e+3,
  132.      0.1e+1
  133. };
  134.  
  135. /* qzero for x in [8,inf]
  136.  * Index 6948, 18.33 digits precision
  137.  */
  138. static double pqzero[] = {
  139.     -0.892266002008000940984692e+2,
  140.     -0.185919536443429938002522e+3,
  141.     -0.111834299204827376112621e+3,
  142.     -0.223002616662141984716992e+2,
  143.     -0.124410267458356384591379e+1,
  144.     -0.8803330304868075181663e-2,
  145. };
  146.  
  147. static double qqzero[] = {
  148.      0.571050241285120619052476e+4,
  149.      0.119511315434346136469526e+5,
  150.      0.726427801692110188369134e+4,
  151.      0.148872312322837565816135e+4,
  152.      0.905937695949931258588188e+2,
  153.      0.1e+1
  154. };
  155.  
  156.  
  157. /* yzero for x in [0,8]
  158.  * Index 6245, 18.78 digits precision
  159.  */
  160. static double pyzero[] = {
  161.     -0.275028667862910958370193e+20,
  162.      0.658747327571955492599940e+20,
  163.     -0.524706558111276494129735e+19,
  164.      0.137562431639934407857134e+18,
  165.     -0.164860581718572947312208e+16,
  166.      0.102552085968639428450917e+14,
  167.     -0.343637122297904037817103e+11,
  168.      0.591521346568688965427383e+8,
  169.     -0.413703549793314855412524e+5
  170. };
  171.  
  172. static double qyzero[] = {
  173.      0.372645883898616588198998e+21,
  174.      0.419241704341083997390477e+19,
  175.      0.239288304349978185743936e+17,
  176.      0.916203803407518526248915e+14,
  177.      0.261306575504108124956848e+12,
  178.      0.579512264070072953738009e+9,
  179.      0.100170264128890626566665e+7,
  180.      0.128245277247899380417633e+4,
  181.      0.1e+1
  182. };
  183.  
  184.  
  185. /* jone for x in [0,8]
  186.  * Index 6050, 20.98 digits precision
  187.  */
  188. static double pjone[] = {
  189.      0.581199354001606143928051e+21,
  190.     -0.667210656892491629802094e+20,
  191.      0.231643358063400229793182e+19,
  192.     -0.358881756991010605074364e+17,
  193.      0.290879526383477540973760e+15,
  194.     -0.132298348033212645312547e+13,
  195.      0.341323418230170053909129e+10,
  196.     -0.469575353064299585976716e+7,
  197.      0.270112271089232341485679e+4
  198. };
  199.  
  200. static double qjone[] = {
  201.      0.116239870800321228785853e+22,
  202.      0.118577071219032099983711e+20,
  203.      0.609206139891752174610520e+17,
  204.      0.208166122130760735124018e+15,
  205.      0.524371026216764971540673e+12,
  206.      0.101386351435867398996705e+10,
  207.      0.150179359499858550592110e+7,
  208.      0.160693157348148780197092e+4,
  209.      0.1e+1
  210. };
  211.  
  212.  
  213. /* pone for x in [8,inf]
  214.  * Index 6749, 18.11 digits precision
  215.  */
  216. static double ppone[] = {
  217.      0.352246649133679798341724e+5,
  218.      0.627588452471612812690057e+5,
  219.      0.313539631109159574238670e+5,
  220.      0.498548320605943384345005e+4,
  221.      0.211152918285396238210572e+3,
  222.      0.12571716929145341558495e+1
  223. };
  224.  
  225. static double qpone[] = {
  226.      0.352246649133679798068390e+5,
  227.      0.626943469593560511888834e+5,
  228.      0.312404063819041039923016e+5,
  229.      0.493039649018108897938610e+4,
  230.      0.203077518913475932229357e+3,
  231.      0.1e+1
  232. };
  233.  
  234. /* qone for x in [8,inf]
  235.  * Index 7149, 18.28 digits precision
  236.  */
  237. static double pqone[] = {
  238.      0.351175191430355282253332e+3,
  239.      0.721039180490447503928086e+3,
  240.      0.425987301165444238988699e+3,
  241.      0.831898957673850827325226e+2,
  242.      0.45681716295512267064405e+1,
  243.      0.3532840052740123642735e-1
  244. };
  245.  
  246. static double qqone[] = {
  247.      0.749173741718091277145195e+4,
  248.      0.154141773392650970499848e+5,
  249.      0.915223170151699227059047e+4,
  250.      0.181118670055235135067242e+4,
  251.      0.103818758546213372877664e+3,
  252.      0.1e+1
  253. };
  254.  
  255.  
  256. /* yone for x in [0,8]
  257.  * Index 6444, 18.24 digits precision
  258.  */
  259. static double pyone[] = {
  260.     -0.292382196153296254310105e+20,
  261.      0.774852068218683964508809e+19,
  262.     -0.344104806308411444618546e+18,
  263.      0.591516076049007061849632e+16,
  264.     -0.486331694256717507482813e+14,
  265.      0.204969667374566218261980e+12,
  266.     -0.428947196885524880182182e+9,
  267.      0.355692400983052605669132e+6
  268. };
  269.  
  270. static double qyone[] = {
  271.      0.149131151130292035017408e+21,
  272.      0.181866284170613498688507e+19,
  273.      0.113163938269888452690508e+17,
  274.      0.475517358888813771309277e+14,
  275.      0.150022169915670898716637e+12,
  276.      0.371666079862193028559693e+9,
  277.      0.726914730719888456980191e+6,
  278.      0.107269614377892552332213e+4,
  279.      0.1e+1
  280. };
  281.  
  282. #else
  283.  
  284. #define PI_ON_FOUR       0.78539816339744830961566084581987572
  285. #define PI_ON_TWO        1.57079632679489661923131269163975144
  286. #define THREE_PI_ON_FOUR 2.35619449019234492884698253745962716
  287. #define TWO_ON_PI        0.63661977236758134307553505349005744
  288.  
  289. static double dzero = 0.0;
  290.  
  291. /* jzero for x in [0,8]
  292.  * Index 5849, 19.22 digits precision
  293.  */
  294. static double pjzero[] = {
  295.      0.4933787251794133561816813446e+21,
  296.     -0.11791576291076105360384408e+21,
  297.      0.6382059341072356562289432465e+19,
  298.     -0.1367620353088171386865416609e+18,
  299.      0.1434354939140346111664316553e+16,
  300.     -0.8085222034853793871199468171e+13,
  301.      0.2507158285536881945555156435e+11,
  302.     -0.4050412371833132706360663322e+8,
  303.      0.2685786856980014981415848441e+5
  304. };
  305.  
  306. static double qjzero[] = {
  307.     0.4933787251794133562113278438e+21,
  308.     0.5428918384092285160200195092e+19,
  309.     0.3024635616709462698627330784e+17,
  310.     0.1127756739679798507056031594e+15,
  311.     0.3123043114941213172572469442e+12,
  312.     0.669998767298223967181402866e+9,
  313.     0.1114636098462985378182402543e+7,
  314.     0.1363063652328970604442810507e+4,
  315.     0.1e+1
  316. };
  317.  
  318. /* pzero for x in [8,inf]
  319.  * Index 6548, 18.16 digits precision
  320.  */
  321. static double ppzero[] = {
  322.     0.2277909019730468430227002627e+5,
  323.     0.4134538663958076579678016384e+5,
  324.     0.2117052338086494432193395727e+5,
  325.     0.348064864432492703474453111e+4,
  326.     0.15376201909008354295771715e+3,
  327.     0.889615484242104552360748e+0
  328. };
  329.  
  330. static double qpzero[] = {
  331.     0.2277909019730468431768423768e+5,
  332.     0.4137041249551041663989198384e+5,
  333.     0.2121535056188011573042256764e+5,
  334.     0.350287351382356082073561423e+4,
  335.     0.15711159858080893649068482e+3,
  336.     0.1e+1
  337. };
  338.  
  339. /* qzero for x in [8,inf]
  340.  * Index 6948, 18.33 digits precision
  341.  */
  342. static double pqzero[] = {
  343.     -0.8922660020080009409846916e+2,
  344.     -0.18591953644342993800252169e+3,
  345.     -0.11183429920482737611262123e+3,
  346.     -0.2230026166621419847169915e+2,
  347.     -0.124410267458356384591379e+1,
  348.     -0.8803330304868075181663e-2,
  349. };
  350.  
  351. static double qqzero[] = {
  352.     0.571050241285120619052476459e+4,
  353.     0.1195113154343461364695265329e+5,
  354.     0.726427801692110188369134506e+4,
  355.     0.148872312322837565816134698e+4,
  356.     0.9059376959499312585881878e+2,
  357.     0.1e+1
  358. };
  359.  
  360.  
  361. /* yzero for x in [0,8]
  362.  * Index 6245, 18.78 digits precision
  363.  */
  364. static double pyzero[] = {
  365.     -0.2750286678629109583701933175e+20,
  366.      0.6587473275719554925999402049e+20,
  367.     -0.5247065581112764941297350814e+19,
  368.      0.1375624316399344078571335453e+18,
  369.     -0.1648605817185729473122082537e+16,
  370.      0.1025520859686394284509167421e+14,
  371.     -0.3436371222979040378171030138e+11,
  372.      0.5915213465686889654273830069e+8,
  373.     -0.4137035497933148554125235152e+5
  374. };
  375.  
  376. static double qyzero[] = {
  377.     0.3726458838986165881989980739e+21,
  378.     0.4192417043410839973904769661e+19,
  379.     0.2392883043499781857439356652e+17,
  380.     0.9162038034075185262489147968e+14,
  381.     0.2613065755041081249568482092e+12,
  382.     0.5795122640700729537380087915e+9,
  383.     0.1001702641288906265666651753e+7,
  384.     0.1282452772478993804176329391e+4,
  385.     0.1e+1
  386. };
  387.  
  388.  
  389. /* jone for x in [0,8]
  390.  * Index 6050, 20.98 digits precision
  391.  */
  392. static double pjone[] = {
  393.      0.581199354001606143928050809e+21,
  394.     -0.6672106568924916298020941484e+20,
  395.      0.2316433580634002297931815435e+19,
  396.     -0.3588817569910106050743641413e+17,
  397.      0.2908795263834775409737601689e+15,
  398.     -0.1322983480332126453125473247e+13,
  399.      0.3413234182301700539091292655e+10,
  400.     -0.4695753530642995859767162166e+7,
  401.      0.270112271089232341485679099e+4
  402. };
  403.  
  404. static double qjone[] = {
  405.     0.11623987080032122878585294e+22,
  406.     0.1185770712190320999837113348e+20,
  407.     0.6092061398917521746105196863e+17,
  408.     0.2081661221307607351240184229e+15,
  409.     0.5243710262167649715406728642e+12,
  410.     0.1013863514358673989967045588e+10,
  411.     0.1501793594998585505921097578e+7,
  412.     0.1606931573481487801970916749e+4,
  413.     0.1e+1
  414. };
  415.  
  416.  
  417. /* pone for x in [8,inf]
  418.  * Index 6749, 18.11 digits precision
  419.  */
  420. static double ppone[] = {
  421.     0.352246649133679798341724373e+5,
  422.     0.62758845247161281269005675e+5,
  423.     0.313539631109159574238669888e+5,
  424.     0.49854832060594338434500455e+4,
  425.     0.2111529182853962382105718e+3,
  426.     0.12571716929145341558495e+1
  427. };
  428.  
  429. static double qpone[] = {
  430.     0.352246649133679798068390431e+5,
  431.     0.626943469593560511888833731e+5,
  432.     0.312404063819041039923015703e+5,
  433.     0.4930396490181088979386097e+4,
  434.     0.2030775189134759322293574e+3,
  435.     0.1e+1
  436. };
  437.  
  438. /* qone for x in [8,inf]
  439.  * Index 7149, 18.28 digits precision
  440.  */
  441. static double pqone[] = {
  442.     0.3511751914303552822533318e+3,
  443.     0.7210391804904475039280863e+3,
  444.     0.4259873011654442389886993e+3,
  445.     0.831898957673850827325226e+2,
  446.     0.45681716295512267064405e+1,
  447.     0.3532840052740123642735e-1
  448. };
  449.  
  450. static double qqone[] = {
  451.     0.74917374171809127714519505e+4,
  452.     0.154141773392650970499848051e+5,
  453.     0.91522317015169922705904727e+4,
  454.     0.18111867005523513506724158e+4,
  455.     0.1038187585462133728776636e+3,
  456.     0.1e+1
  457. };
  458.  
  459.  
  460. /* yone for x in [0,8]
  461.  * Index 6444, 18.24 digits precision
  462.  */
  463. static double pyone[] = {
  464.     -0.2923821961532962543101048748e+20,
  465.      0.7748520682186839645088094202e+19,
  466.     -0.3441048063084114446185461344e+18,
  467.      0.5915160760490070618496315281e+16,
  468.     -0.4863316942567175074828129117e+14,
  469.      0.2049696673745662182619800495e+12,
  470.     -0.4289471968855248801821819588e+9,
  471.      0.3556924009830526056691325215e+6
  472. };
  473.  
  474. static double qyone[] = {
  475.     0.1491311511302920350174081355e+21,
  476.     0.1818662841706134986885065935e+19,
  477.     0.113163938269888452690508283e+17,
  478.     0.4755173588888137713092774006e+14,
  479.     0.1500221699156708987166369115e+12,
  480.     0.3716660798621930285596927703e+9,
  481.     0.726914730719888456980191315e+6,
  482.     0.10726961437789255233221267e+4,
  483.     0.1e+1
  484. };
  485.  
  486. #endif /* ATARI && __PUREC__ */
  487.  
  488. f_real()
  489. {
  490. struct value a;
  491.     push( Gcomplex(&a,real(pop(&a)), 0.0) );
  492. }
  493.  
  494. f_imag()
  495. {
  496. struct value a;
  497.     push( Gcomplex(&a,imag(pop(&a)), 0.0) );
  498. }
  499.  
  500. f_arg()
  501. {
  502. struct value a;
  503.     push( Gcomplex(&a,angle(pop(&a)), 0.0) );
  504. }
  505.  
  506. f_conjg()
  507. {
  508. struct value a;
  509.     (void) pop(&a);
  510.     push( Gcomplex(&a,real(&a),-imag(&a) ));
  511. }
  512.  
  513. f_sin()
  514. {
  515. struct value a;
  516.     (void) pop(&a);
  517.     push( Gcomplex(&a,sin(real(&a))*cosh(imag(&a)), cos(real(&a))*sinh(imag(&a))) );
  518. }
  519.  
  520. f_cos()
  521. {
  522. struct value a;
  523.     (void) pop(&a);
  524.     push( Gcomplex(&a,cos(real(&a))*cosh(imag(&a)), -sin(real(&a))*sinh(imag(&a))));
  525. }
  526.  
  527. f_tan()
  528. {
  529. struct value a;
  530. register double den;
  531.     (void) pop(&a);
  532.     if (imag(&a) == 0.0)
  533.         push( Gcomplex(&a,tan(real(&a)),0.0) );
  534.     else {
  535.         den = cos(2*real(&a))+cosh(2*imag(&a));
  536.         if (den == 0.0) {
  537.             undefined = TRUE;
  538.             push( &a );
  539.         }
  540.         else
  541.             push( Gcomplex(&a,sin(2*real(&a))/den, sinh(2*imag(&a))/den) );
  542.     }
  543. }
  544.  
  545. f_asin()
  546. {
  547. struct value a;
  548. register double alpha, beta, x, y;
  549.     (void) pop(&a);
  550.     x = real(&a); y = imag(&a);
  551.     if (y == 0.0) {
  552.         if (fabs(x) > 1.0) {
  553.             undefined = TRUE;
  554.             push(Gcomplex(&a,0.0, 0.0));
  555.         } else
  556.             push( Gcomplex(&a,asin(x),0.0) );
  557.     } else {
  558.         beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
  559.         alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
  560.         push( Gcomplex(&a,asin(beta), log(alpha + sqrt(alpha*alpha-1))) );
  561.     }
  562. }
  563.  
  564. f_acos()
  565. {
  566. struct value a;
  567. register double alpha, beta, x, y;
  568.     (void) pop(&a);
  569.     x = real(&a); y = imag(&a);
  570.     if (y == 0.0) {
  571.         if (fabs(x) > 1.0) {
  572.             undefined = TRUE;
  573.             push(Gcomplex(&a,0.0, 0.0));
  574.         } else
  575.             push( Gcomplex(&a,acos(x),0.0) );
  576.     } else {
  577.         alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
  578.         beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
  579.         push( Gcomplex(&a,acos(beta), log(alpha + sqrt(alpha*alpha-1))) );
  580.     }
  581. }
  582.  
  583. f_atan()
  584. {
  585. struct value a;
  586. register double x, y, u, v, w, z;
  587.     (void) pop(&a);
  588.     x = real(&a); y = imag(&a);
  589.     if (y == 0.0)
  590.         push( Gcomplex(&a,atan(x), 0.0) );
  591.     else if (x == 0.0 && fabs(y) == 1.0) {
  592.         undefined = TRUE;
  593.         push(Gcomplex(&a,0.0, 0.0));
  594.     } else {
  595.             if (x >= 0) {
  596.                 u = x;
  597.             v = y;
  598.         } else {
  599.                 u = -x;
  600.             v = -y;
  601.         }
  602.         
  603.             z = atan(2*u/(1-u*u-v*v));
  604.         w = log((u*u+(v+1)*(v+1))/(u*u+(v-1)*(v-1)))/4;
  605.         if (z < 0)
  606.                 z = z + 2*PI_ON_TWO;
  607.         if (x < 0) {
  608.                 z = -z;
  609.             w = -w;
  610.         }
  611.         push( Gcomplex(&a,0.5*z, w) );
  612.     }
  613. }
  614.  
  615. f_sinh()
  616. {
  617. struct value a;
  618.     (void) pop(&a);
  619.     push( Gcomplex(&a,sinh(real(&a))*cos(imag(&a)), cosh(real(&a))*sin(imag(&a))) );
  620. }
  621.  
  622. f_cosh()
  623. {
  624. struct value a;
  625.     (void) pop(&a);
  626.     push( Gcomplex(&a,cosh(real(&a))*cos(imag(&a)), sinh(real(&a))*sin(imag(&a))) );
  627. }
  628.  
  629. f_tanh()
  630. {
  631. struct value a;
  632. register double den;
  633.     (void) pop(&a);
  634.     den = cosh(2*real(&a)) + cos(2*imag(&a));
  635.     push( Gcomplex(&a,sinh(2*real(&a))/den, sin(2*imag(&a))/den) );
  636. }
  637.  
  638. f_int()
  639. {
  640. struct value a;
  641.     push( Ginteger(&a,(int)real(pop(&a))) );
  642. }
  643.  
  644.  
  645. f_abs()
  646. {
  647. struct value a;
  648.     (void) pop(&a);
  649.     switch (a.type) {
  650.         case INTGR:
  651.             push( Ginteger(&a,abs(a.v.int_val)) );            
  652.             break;
  653.         case CMPLX:
  654.             push( Gcomplex(&a,magnitude(&a), 0.0) );
  655.     }
  656. }
  657.  
  658. f_sgn()
  659. {
  660. struct value a;
  661.     (void) pop(&a);
  662.     switch(a.type) {
  663.         case INTGR:
  664.             push( Ginteger(&a,(a.v.int_val > 0) ? 1 : 
  665.                     (a.v.int_val < 0) ? -1 : 0) );
  666.             break;
  667.         case CMPLX:
  668.             push( Ginteger(&a,(a.v.cmplx_val.real > 0.0) ? 1 : 
  669.                     (a.v.cmplx_val.real < 0.0) ? -1 : 0) );
  670.             break;
  671.     }
  672. }
  673.  
  674.  
  675. f_sqrt()
  676. {
  677. struct value a;
  678. register double mag, ang;
  679.     (void) pop(&a);
  680.     mag = sqrt(magnitude(&a));
  681.     if (imag(&a) == 0.0 && real(&a) < 0.0)
  682.         push( Gcomplex(&a,0.0,mag) );
  683.     else
  684.     {
  685.         if ( (ang = angle(&a)) < 0.0)
  686.             ang += 2*Pi;
  687.         ang /= 2;
  688.         push( Gcomplex(&a,mag*cos(ang), mag*sin(ang)) );
  689.     }
  690. }
  691.  
  692.  
  693. f_exp()
  694. {
  695. struct value a;
  696. register double mag, ang;
  697.     (void) pop(&a);
  698.     mag = exp(real(&a));
  699.     ang = imag(&a);
  700.     push( Gcomplex(&a,mag*cos(ang), mag*sin(ang)) );
  701. }
  702.  
  703.  
  704. f_log10()
  705. {
  706. struct value a;
  707. register double l10;;
  708.     (void) pop(&a);
  709.     l10 = log(10.0);    /***** replace with a constant! ******/
  710.     push( Gcomplex(&a,log(magnitude(&a))/l10, angle(&a)/l10) );
  711. }
  712.  
  713.  
  714. f_log()
  715. {
  716. struct value a;
  717.     (void) pop(&a);
  718.     push( Gcomplex(&a,log(magnitude(&a)), angle(&a)) );
  719. }
  720.  
  721.  
  722. f_floor()
  723. {
  724. struct value a;
  725.  
  726.     (void) pop(&a);
  727.     switch (a.type) {
  728.         case INTGR:
  729.             push( Ginteger(&a,(int)floor((double)a.v.int_val)));            
  730.             break;
  731.         case CMPLX:
  732.             push( Ginteger(&a,(int)floor(a.v.cmplx_val.real)));
  733.     }
  734. }
  735.  
  736.  
  737. f_ceil()
  738. {
  739. struct value a;
  740.  
  741.     (void) pop(&a);
  742.     switch (a.type) {
  743.         case INTGR:
  744.             push( Ginteger(&a,(int)ceil((double)a.v.int_val)));            
  745.             break;
  746.         case CMPLX:
  747.             push( Ginteger(&a,(int)ceil(a.v.cmplx_val.real)));
  748.     }
  749. }
  750.  
  751. /* bessel function approximations */
  752. double jzero(x)
  753. double x;
  754. {
  755. double p, q, x2;
  756. int n;
  757.  
  758.     x2 = x * x;
  759.     p = pjzero[8];
  760.     q = qjzero[8];
  761.     for (n=7; n>=0; n--) {
  762.         p = p*x2 + pjzero[n];
  763.         q = q*x2 + qjzero[n];
  764.     }
  765.     return(p/q);
  766. }
  767.  
  768. double pzero(x)
  769. double x;
  770. {
  771. double p, q, z, z2;
  772. int n;
  773.  
  774.     z = 8.0 / x;
  775.     z2 = z * z;
  776.     p = ppzero[5];
  777.     q = qpzero[5];
  778.     for (n=4; n>=0; n--) {
  779.         p = p*z2 + ppzero[n];
  780.         q = q*z2 + qpzero[n];
  781.     }
  782.     return(p/q);
  783. }
  784.  
  785. double qzero(x)
  786. double x;
  787. {
  788. double p, q, z, z2;
  789. int n;
  790.  
  791.     z = 8.0 / x;
  792.     z2 = z * z;
  793.     p = pqzero[5];
  794.     q = qqzero[5];
  795.     for (n=4; n>=0; n--) {
  796.         p = p*z2 + pqzero[n];
  797.         q = q*z2 + qqzero[n];
  798.     }
  799.     return(p/q);
  800. }
  801.  
  802. double yzero(x)
  803. double x;
  804. {
  805. double p, q, x2;
  806. int n;
  807.  
  808.     x2 = x * x;
  809.     p = pyzero[8];
  810.     q = qyzero[8];
  811.     for (n=7; n>=0; n--) {
  812.         p = p*x2 + pyzero[n];
  813.         q = q*x2 + qyzero[n];
  814.     }
  815.     return(p/q);
  816. }
  817.  
  818. double rj0(x)
  819. double x;
  820. {
  821.     if ( x <= 0.0 )
  822.         x = -x;
  823.     if ( x < 8.0 )
  824.         return(jzero(x));
  825.     else
  826.         return( sqrt(TWO_ON_PI/x) *
  827.             (pzero(x)*cos(x-PI_ON_FOUR) - 8.0/x*qzero(x)*sin(x-PI_ON_FOUR)) );
  828.  
  829. }
  830.  
  831. double ry0(x)
  832. double x;
  833. {
  834.     if ( x < 0.0 )
  835.         return(dzero/dzero); /* error */
  836.     if ( x < 8.0 )
  837.         return( yzero(x) + TWO_ON_PI*rj0(x)*log(x) );
  838.     else
  839.         return( sqrt(TWO_ON_PI/x) *
  840.             (pzero(x)*sin(x-PI_ON_FOUR) + 
  841.             (8.0/x)*qzero(x)*cos(x-PI_ON_FOUR)) );
  842.  
  843. }
  844.  
  845.  
  846. double jone(x)
  847. double x;
  848. {
  849. double p, q, x2;
  850. int n;
  851.  
  852.     x2 = x * x;
  853.     p = pjone[8];
  854.     q = qjone[8];
  855.     for (n=7; n>=0; n--) {
  856.         p = p*x2 + pjone[n];
  857.         q = q*x2 + qjone[n];
  858.     }
  859.     return(p/q);
  860. }
  861.  
  862. double pone(x)
  863. double x;
  864. {
  865. double p, q, z, z2;
  866. int n;
  867.  
  868.     z = 8.0 / x;
  869.     z2 = z * z;
  870.     p = ppone[5];
  871.     q = qpone[5];
  872.     for (n=4; n>=0; n--) {
  873.         p = p*z2 + ppone[n];
  874.         q = q*z2 + qpone[n];
  875.     }
  876.     return(p/q);
  877. }
  878.  
  879. double qone(x)
  880. double x;
  881. {
  882. double p, q, z, z2;
  883. int n;
  884.  
  885.     z = 8.0 / x;
  886.     z2 = z * z;
  887.     p = pqone[5];
  888.     q = qqone[5];
  889.     for (n=4; n>=0; n--) {
  890.         p = p*z2 + pqone[n];
  891.         q = q*z2 + qqone[n];
  892.     }
  893.     return(p/q);
  894. }
  895.  
  896. double yone(x)
  897. double x;
  898. {
  899. double p, q, x2;
  900. int n;
  901.  
  902.     x2 = x * x;
  903.     p = 0.0;
  904.     q = qyone[8];
  905.     for (n=7; n>=0; n--) {
  906.         p = p*x2 + pyone[n];
  907.         q = q*x2 + qyone[n];
  908.     }
  909.     return(p/q);
  910. }
  911.  
  912. double rj1(x)
  913. double x;
  914. {
  915. double v,w;
  916.     v = x;
  917.     if ( x < 0.0 )
  918.         x = -x;
  919.     if ( x < 8.0 )
  920.         return(v*jone(x));
  921.     else {
  922.         w = sqrt(TWO_ON_PI/x) *
  923.             (pone(x)*cos(x-THREE_PI_ON_FOUR) - 
  924.                8.0/x*qone(x)*sin(x-THREE_PI_ON_FOUR)) ;
  925.         if (v < 0.0)
  926.             w = -w;
  927.         return( w );
  928.     }
  929. }
  930.  
  931. double ry1(x)
  932. double x;
  933. {
  934.     if ( x <= 0.0 )
  935.         return(dzero/dzero); /* error */
  936.     if ( x < 8.0 )
  937.         return( x*yone(x) + TWO_ON_PI*(rj1(x)*log(x) - 1.0/x) );
  938.     else
  939.         return( sqrt(TWO_ON_PI/x) *
  940.             (pone(x)*sin(x-THREE_PI_ON_FOUR) + 
  941.             (8.0/x)*qone(x)*cos(x-THREE_PI_ON_FOUR)) );
  942. }
  943.  
  944.  
  945. f_besj0()    
  946. {
  947. struct value a;
  948. double x;
  949.     (void) pop(&a);
  950.     if (imag(&a) > zero)
  951.         int_error("can only do bessel functions of reals",NO_CARET);
  952.     push( Gcomplex(&a,rj0(real(&a)),0.0) );
  953. }
  954.  
  955.  
  956. f_besj1()    
  957. {
  958. struct value a;
  959. double x;
  960.     (void) pop(&a);
  961.     if (imag(&a) > zero)
  962.         int_error("can only do bessel functions of reals",NO_CARET);
  963.     push( Gcomplex(&a,rj1(real(&a)),0.0) );
  964. }
  965.  
  966.  
  967. f_besy0()    
  968. {
  969. struct value a;
  970. double x;
  971.     (void) pop(&a);
  972.     if (imag(&a) > zero)
  973.         int_error("can only do bessel functions of reals",NO_CARET);
  974.     if (real(&a) > 0.0)
  975.         push( Gcomplex(&a,ry0(real(&a)),0.0) );
  976.     else {
  977.         push( Gcomplex(&a,0.0,0.0) );
  978.         undefined = TRUE ;
  979.     }
  980. }
  981.  
  982.  
  983. f_besy1()    
  984. {
  985. struct value a;
  986. double x;
  987.     (void) pop(&a);
  988.     if (imag(&a) > zero)
  989.         int_error("can only do bessel functions of reals",NO_CARET);
  990.     if (real(&a) > 0.0)
  991.         push( Gcomplex(&a,ry1(real(&a)),0.0) );
  992.     else {
  993.         push( Gcomplex(&a,0.0,0.0) );
  994.         undefined = TRUE ;
  995.     }
  996. }
  997.